/* * Copyright (C) 2012 Niall 'Rivernile' Scott * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors or contributors be held liable for * any damages arising from the use of this software. * * The aforementioned copyright holder(s) hereby grant you a * non-transferrable right to use this software for any purpose (including * commercial applications), and to modify it and redistribute it, subject to * the following conditions: * * 1. This notice may not be removed or altered from any file it appears in. * * 2. Any modifications made to this software, except those defined in * clause 3 of this agreement, must be released under this license, and * the source code of any modifications must be made available on a * publically accessible (and locateable) website, or sent to the * original author of this software. * * 3. Software modifications that do not alter the functionality of the * software but are simply adaptations to a specific environment are * exempt from clause 2. */ package uk.org.rivernile.edinburghbustracker.android.maps; import android.content.Context; import android.location.Address; import android.location.Geocoder; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import java.io.IOException; import java.util.HashSet; import java.util.List; import uk.org.rivernile.android.utils.SimpleResultLoader; /** * The GeoSearchLoader takes a query parameter and uses the system Geocoding * APIs to return locations within the boundaries which match the query. * * @author Niall Scott */ public class GeoSearchLoader extends SimpleResultLoader<HashSet<MarkerOptions>> { private static final double BOUNDS_NORTH = 56.000000; private static final double BOUNDS_SOUTH = 55.819447; private static final double BOUNDS_WEST = -3.403363; private static final double BOUNDS_EAST = -2.864143; private static final int MAX_GEO_RESULTS = 10; private final String query; /** * Create a new GeoSearchLoader, specifying the query to use on the * Geocoding service. * * @param context A Context instance. * @param query The query to look up. */ public GeoSearchLoader(final Context context, final String query) { super(context); if(query == null) { throw new IllegalArgumentException("query must not be null."); } this.query = query; } /** * {@inheritDoc} */ @Override public HashSet<MarkerOptions> loadInBackground() { final HashSet<MarkerOptions> result = new HashSet<MarkerOptions>(); final Geocoder geo = new Geocoder(getContext()); final List<Address> addressList; try { addressList = geo.getFromLocationName(query, MAX_GEO_RESULTS, BOUNDS_SOUTH, BOUNDS_WEST, BOUNDS_NORTH, BOUNDS_EAST); } catch(IOException e) { return result; } if(addressList != null) { MarkerOptions mo; final StringBuilder sb = new StringBuilder(); String locality, postalCode; for(Address a : addressList) { mo = new MarkerOptions(); mo.draggable(false); mo.anchor(0.5f, 1.f); mo.position(new LatLng(a.getLatitude(), a.getLongitude())); mo.icon(BitmapDescriptorFactory.defaultMarker()); mo.title(a.getFeatureName()); locality = a.getLocality(); postalCode = a.getPostalCode(); if(locality != null && postalCode != null) { sb.append(locality).append(',').append(' ') .append(postalCode); mo.snippet(sb.toString()); } else if(locality != null) { mo.snippet(locality); } else if(postalCode != null) { mo.snippet(postalCode); } result.add(mo); sb.setLength(0); } } return result; } }